/*
 * The MIT License (MIT)
 *
 * Copyright (c) 2014 abel533@gmail.com
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
package com.honeybees.framework.mybatis.util;

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import javax.sql.DataSource;

import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.ResultMap;
import org.apache.ibatis.mapping.ResultMapping;
import org.apache.ibatis.mapping.SqlSource;
import org.apache.ibatis.session.Configuration;

/**
 * <dl>
 * <dt><b> 根据当前的MappedStatement，创建新的MappedStatement，用于查询数据总条数。 </b></dt>
 * <p>
 * <dd>https://github.com/pagehelper/Mybatis-PageHelper.git</dd>
 * </dl>
 * <p>
 * Copyright (C) All rights reserved.
 * </p>
 *
 * @author 李远明
 * @since 2016-07-18 09:23:48
 */
public final class MappedStatementUtils {

    private static final List<ResultMapping> EMPTY_RESULTMAPPING = new ArrayList<ResultMapping>(0);

    private static final String SUFFIX = "_Count";

    /**
     * <dl>
     * <dt><b> 根据当前的MappedStatement，创建新的MappedStatement，用于查询数据总条数。 </b></dt>
     * <p>
     * <dd>用于MyBatis分页查询时，查询数据总条数。</dd>
     * </dl>
     *
     * @param ms
     * @return
     * @author 李远明
     * @version 2016年7月18日 上午9:25:19
     */
    public static MappedStatement newCountMappedStatement(MappedStatement ms) {
        Configuration configuration = ms.getConfiguration();
        String id = ms.getId();
        SqlSource sqlSource = ms.getSqlSource(); // PageDynamicSqlSource

        MappedStatement.Builder builder = new MappedStatement.Builder(configuration, id + SUFFIX, sqlSource,
                ms.getSqlCommandType());
        builder.resource(ms.getResource());
        builder.fetchSize(ms.getFetchSize());
        builder.statementType(ms.getStatementType());
        builder.keyGenerator(ms.getKeyGenerator());
        String[] keyProperties = ms.getKeyProperties();
        if (keyProperties != null && keyProperties.length != 0) {
            StringBuilder keyProps = new StringBuilder();
            for (String keyProperty : keyProperties) {
                keyProps.append(keyProperty).append(",");
            }
            keyProps.delete(keyProps.length() - 1, keyProps.length());
            builder.keyProperty(keyProps.toString());
        }
        builder.timeout(ms.getTimeout());
        builder.parameterMap(ms.getParameterMap());

        // SQL Count查询，返回值int
        List<ResultMap> resultMaps = new ArrayList<ResultMap>();
        ResultMap resultMap = new ResultMap.Builder(configuration, id, int.class, EMPTY_RESULTMAPPING).build();
        resultMaps.add(resultMap);
        builder.resultMaps(resultMaps);
        builder.resultSetType(ms.getResultSetType());
        builder.cache(ms.getCache());
        builder.flushCacheRequired(ms.isFlushCacheRequired());
        builder.useCache(ms.isUseCache());

        return builder.build();
    }

    /**
     * <dl>
     * <dt><b> 从数据库元数据中获取数据库名称 </b></dt>
     * <p>
     * <dd>功能描述</dd>
     * </dl>
     *
     * @param mappedStatement
     * @return
     * @throws SQLException
     * @author 李远明
     * @version 2016-07-22 10:11:20
     */
    public static String getDatabaseName(MappedStatement mappedStatement) throws SQLException {
        DataSource dataSource = mappedStatement.getConfiguration().getEnvironment().getDataSource();
        Connection connection = dataSource.getConnection();
        DatabaseMetaData dbmd = connection.getMetaData();
        return dbmd.getDatabaseProductName();
    }

}
